﻿using System;
using System.IO;
using System.Text;
using Dan.Common.CusException;

namespace Dan.Common
{
    /// <summary>
    /// 日志助手類
    /// </summary>
    public class LogHelper
    {
        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="logType">日志类型</param>
        /// <param name="content">日志內容</param>
        public static void WriteLongLog(string logType, string content)
        {
            string newLine = Environment.NewLine;

            string path = Path.Combine($"logs/{logType}/{DateTime.Now:yyyy-MM-dd}-{logType}.txt");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }

            //采用追加模式来写日志
            using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write))
            {
                StreamWriter writer = new StreamWriter(fs, Encoding.UTF8);
                var str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + newLine + content + newLine + newLine;
                writer.WriteLine(str);
                writer.Flush();
            }
        }

        /// <summary>
        /// 始終都是創建新的文件
        /// </summary>
        /// <param name="logType"></param>
        /// <param name="content"></param>
        public static void WriteCreateNewLog(string logType, string content)
        {
            string newLine = Environment.NewLine;
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var index = baseDirectory.IndexOf("bin", StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                baseDirectory = baseDirectory.Remove(index);
            }

            string path = baseDirectory + @"log\" + logType + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + " - " +
                          logType + ".txt";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }


            using (var fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                StreamWriter writer = new StreamWriter(fs, Encoding.UTF8);
                var str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + newLine + content + newLine + newLine;
                writer.WriteLine(str);
                writer.Flush();
            }
        }

        /// <summary>
        /// 打印錯誤日誌信息
        /// </summary>
        /// <param name="ri"></param>
        /// <param name="ex"></param>
        public static void WriteExceptionLog(RequestInfo ri, Exception ex)
        {
            var str = GetExceptionStr(ri, ex);
            WriteLongLog("exception", str); //寫入日志
        }

        public static string GetExceptionStr(RequestInfo ri, Exception ex)
        {
            var newLine = Environment.NewLine;

            var sb = new StringBuilder();
            sb.AppendLine(
                "//**********************************************************************************************************************");
            sb.AppendLine($"异常时间：({DateTime.Now:yyyy-MM-dd HH:mm:ss fff})");


            sb.AppendLine();
            sb.AppendLine($"出错页面：({ri.Path})");
            sb.AppendLine($"query参数信息：({ri.Query})");
            sb.AppendLine($"form参数信息：({ri.FormData})");
            sb.AppendLine($"header参数信息：({ri.Header})");
            sb.AppendLine();

            string message = ex.Message;
            if (ex is MsgException)
            {
                message = $"{((MsgException) ex).Message} {message}";
            }

            sb.AppendLine($"异常信息：({message})");
            sb.AppendLine($"异常方法：({ex.TargetSite})");
            sb.AppendLine($"异常来源：({ex.Source})");
            sb.AppendLine($"异常处理：" + newLine + ex.StackTrace);
            sb.AppendLine($"异常实例：" + newLine + ex.InnerException);
            sb.AppendLine(
                "//**********************************************************************************************************************");
            return sb.ToString();
        }
    }
}